#ifndef __LYNX_AUDIO_MANAGER_HPP_INCLUDED__
#define __LYNX_AUDIO_MANAGER_HPP_INCLUDED__

#include "LynxSound.hpp"
#include "LynxAudioReader.hpp"
#include "LynxSoundSource.hpp"

namespace Lynx
{
namespace Audio
{

////////////////////////////////////////////////////////////////////////////////
//! \brief The main class.
/*!
 * nothing.
 */
class AudioManager : public virtual Myth::ReferenceCounter
{
public:
    ////////////////////////////////////////////////////////////////////////////
    //! \brief Returns if the manager is active.
    /*!
     * \return True if the manager is active, false otherwise.
     */
    virtual bool is_manager_active(void) const = 0;


    ////////////////////////////////////////////////////////////////////////////
    //! \brief Activates the manager.
    /*!
     * \return True is the manager is activated, false if something went wrong.
     *
     * \param[in] device_name The name of the device you want to activate.
     *
     * \throw Exception If the device you specify couldn't be opened, it will
     *                  throw an invalid parameter exception.
     *
     * \throw Exception If the standard device couldn't be opened, it will throw
     *                  an internal error exception.
     *
     * \throw Exception If the context couldn't be created, it will throw an
     *                  internal error exception.
     *
     * \throw Exception If the context couldn't be set as the current context,
     *                  it will throw an internal error exception.
     */
    virtual bool activate_manager(const char *device_name = 0) = 0;


    ////////////////////////////////////////////////////////////////////////////
    //! \brief Deactivates the manager if it's currently active.
    /*!
     * This function also cleans everything up.
     *
     * \throw Exception If the manager is not active, it will throw an invalid
     *                  state exception.
     */
    virtual void deactivate_manager(void) = 0;


    ////////////////////////////////////////////////////////////////////////////
    //! \brief Returns the manager name, this is the same as the device name.
    /*!
     * \return The name of the manager
     *
     * \throw Exception If the manager is not active, it will throw an invalid
     *                  state exception.
     */
    virtual std::string get_manager_name(void) const = 0;


    ////////////////////////////////////////////////////////////////////////////
    //! \brief Returns all the possible devices that can be activated.
    /*!
     * \return A vector containing all the device names.
     */
    virtual std::vector<std::string> get_possible_device_names(void) const = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual SoundSource *create_static_source(Myth::Stream::Input *input,
                                         const std::string &name) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual SoundSource *create_streaming_source(Myth::Stream::Input *input,
                                            const std::string &name) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual SoundSource *create_debug_mono_source(const std::string &name) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual SoundSource *create_debug_stereo_source(const std::string &name) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual uint32_t get_source_amount(void) const = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual SoundSource *get_source(uint32_t index) const = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual SoundSource *get_source(const std::string &name) const = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual bool remove_source(uint32_t index) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual bool remove_source(const std::string &name) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual bool remove_all_sources(void) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual Sound *create_sound(SoundSource *source,
                                bool play_looped = false,
                                bool start_paused = false) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual Sound *create_sound(SoundSource *source,
                                Myth::Math::Vector3f pos,
                                bool play_looped = false,
                                bool start_paused = false) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual void play_all_sounds(void) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual void pause_all_sounds(void) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual void stop_all_sounds(void) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual uint32_t get_sound_amount(void) const = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual Sound *get_sound(uint32_t index) const = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual bool remove_sound(uint32_t index) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual bool remove_all_sounds(void) = 0;


    ////////////////////////////////////////////////////////////////////////////
    virtual void add_audio_reader_loader(AudioReaderLoader *loader) = 0;
};

} // namespace Audio
} // namespace Lynx

#endif // __LYNX_AUDIO_MANAGER_HPP_INCLUDED__

